﻿using IntelligentStorWpfApp.Controller;
using log4net;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using WPFMediaKit.DirectShow.Controls;
using IntelligentStorWpfApp.Model;
using System.Collections.Generic;
using System.Threading;
using IntelligentStorWpfApp.Interface;
using IntelligentStorWpfApp.Services;
using System;

namespace IntelligentStorWpfApp.View
{
    /// <summary>
    /// FaceIdentify.xaml 的交互逻辑
    /// </summary>
    public partial class FaceIdentify : Window
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(CabinetWindow));
        private UserController uscontroller = new UserController();
        private OperationLogInterface opInterface = new OperationLogServices();
        public const string faceFilePath = "Image/Faces";
        DrawingGroup dGroup;
        DrawingImage dImageSource;
        List<User> listUsers=new List<User>();
        public FaceIdentify()
        {
            InitializeComponent();
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
        }

        private void FaceIdentify_Loaded(object sender, RoutedEventArgs e)
        {
            //if(App.user==null)
            //{
            //    m_btInputFace.Background = System.Windows.Media.Brushes.Gray;
            //    m_btInputFace.IsEnabled=false;
            //}
            if (MultimediaUtil.VideoInputNames.Length <= 0)
            {
                MessageBox.Show("电脑没有安装任何摄像头", "Error", MessageBoxButton.OK, MessageBoxImage.Error);

            }
            else
            {
                listUsers = uscontroller.getAllUsers();
                startCapture();
            }
        }

        private void m_btInputFace_Click(object sender, RoutedEventArgs e)
        {
            bool loginflag = false;
            RenderTargetBitmap bmp = new RenderTargetBitmap(
            (int)vce.ActualWidth,
            (int)vce.ActualHeight,
            96, 96, PixelFormats.Pbgra32);
            bmp.Render(vce);
            BitmapEncoder encoder = new JpegBitmapEncoder();//默认使用JPG格式保存，可以切换成其他格式，因为JPG格式的文件更小，所以这里推荐使用
            encoder.Frames.Add(BitmapFrame.Create(bmp));
            using (MemoryStream ms = new MemoryStream())
            {
                encoder.Save(ms);
                byte[] data = ms.ToArray();//此处不必保存,因为之后将直接用到byte[]
                //DirectoryInfo root = new DirectoryInfo(faceFilePath);
                //string newFacefile = faceFilePath + "//" + (root.GetFiles().Length + 1).ToString() + ".jpg";
                //File.WriteAllBytes(newFacefile, data);//保存到本地
                if (App.user != null)
                {
                    loginflag = true;
                    App.user.FaceId = data;
                    if (uscontroller.UpdateUserFace(App.user))
                    {
                        MessageBox.Show("录入成功!");
                    }
                    else
                    {
                        MessageBox.Show("录入失败!");
                        return;
                    }
                 }
                else
                {
                    App.user = new User();
                    App.user.FaceId = data;
                }
               // deleteFile(newFacefile);
            }
            if (loginflag)
            {
                vce.Pause();
                Thread.Sleep(2000);
                vce.Play();
            }
            else
            {
                Register winRegister = new Register();
                winRegister.Show();
                this.Close();
            }
            //startCapture();
        }

        private void startCapture()
        {
            vce.Stop();
            dGroup = new DrawingGroup();
            dImageSource = new DrawingImage(dGroup);
            img1.Source = dImageSource;
            string[] inputNames = MultimediaUtil.VideoInputNames;
            if (inputNames.Length > 0)
            {
                vce.VideoCaptureSource = inputNames[0];

            }
            start();
        }
        private void start()
        {
            try
            {
                //开个新线程
                Task.Factory.StartNew(() =>
                {
                //同步前端线程
                Dispatcher.Invoke(() =>
                    {
                    //根据前端视频流控件的长宽高获取最佳的bitmap对象
                    RenderTargetBitmap bmp = new RenderTargetBitmap(
                       (int)vce.ActualWidth,
                       (int)vce.ActualHeight,
                       96, 96, PixelFormats.Default);
                    //渲染bitmap
                    bmp.Render(vce);
                        BitmapEncoder encoder = new JpegBitmapEncoder();
                        encoder.Frames.Add(BitmapFrame.Create(bmp));
                        using (MemoryStream ms = new MemoryStream())
                        {
                            encoder.Save(ms);
                            byte[] captureData = ms.ToArray();
                            TaskAwaiter<JObject> awaiter = TFaceDetect(captureData).GetAwaiter();
                            awaiter.OnCompleted(() =>
                            {
                            //创建同步UI线程
                            Dispatcher.Invoke(() =>
                                {
                                    JObject result = awaiter.GetResult();
                                //开始串结果文本
                                string content = "人脸数量: " + result["result_num"] + "\r\n";
                                    if (result["result_num"].ToString() != "0")
                                    {
                                        JToken Rresult = result["result"][0];
                                        content += "人脸置信度: " + Rresult["face_probability"] + "\r\n";
                                        int left = (int)Rresult["location"]["left"];
                                        int top = (int)Rresult["location"]["top"];
                                        int width = (int)Rresult["location"]["width"];
                                        int height = (int)Rresult["location"]["height"];
                                        string cusgender = Rresult["gender"].ToString() == "male" ? "男" : "女";
                                        content += "性别: " + cusgender + "\r\n";
                                        content += "年龄: " + (int)Rresult["age"] + "\r\n";
                                        content += "颜值: " + (int)Rresult["beauty"] + "\r\n";
                                    //if (left > 0 && top > 0 && width > 0 && height > 0)
                                    //    CreateDrawingVisualRectangle(new Rect(left, top, width, height));
                                }
                                });
                            });

                        #region
                        /*
                        TaskAwaiter<JObject> awaiterIdentify = TFaceIdentify(captureData).GetAwaiter();
                        awaiterIdentify.OnCompleted(() =>
                        {

                            Dispatcher.Invoke(new Action(() =>
                            {
                                JObject result = awaiterIdentify.GetResult();
                                if (result["error_code"] != null)
                                    txt2.Text = "未识别有效人脸";
                                else
                                {
                                    uint num = (uint)result["result_num"];
                                    JToken Rresult = result["result"][0];
                                    string group_id = (string)Rresult["group_id"];
                                    string uid = (string)Rresult["uid"];
                                    string user_info = (string)Rresult["user_info"];
                                    string scores = Rresult["scores"][0].ToString();
                                    txt2.Text = num + "," + uid + "\r\n" + scores;
                                }
                            }));
                        });
                        */
                        #endregion
                    }
                    });
                });
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString(),"error",MessageBoxButton.OK,MessageBoxImage.Error);
            }
        }
        private void CreateDrawingVisualRectangle(Rect rect)
        {
            using (DrawingContext dc = dGroup.Open())
            {
                // Draw a rectangle at full opacity.
                //dc.DrawRectangle(Brushes.Transparent, shapeOutlinePen, rect);
                Canvas.SetLeft(img1, rect.X);
                Canvas.SetTop(img1, rect.Y - 20);
            }

        }
        public Task<JObject> TFaceDetect(byte[] captureData)
        {
            return Task.Run(() =>
            {
                JObject result = FaceDemo.FaceDetect(captureData);
                return result;
            });
        }

        public Task<JObject> TFaceIdentify(byte[] captureData)
        {
            return Task.Run(() =>
            {

                JObject result = FaceDemo.IdentifyDemo(captureData);
                return result;
            });
        }

        public Task<JObject> TFaceCompare(byte[][] captureData)
        {
            return Task.Run(() =>
            {

                JObject result = FaceDemo.FaceMatch(captureData);
                return result;
            });
        }

        private void m_btIdentify_Click(object sender, RoutedEventArgs e)
        {
            List<User> listFaceIds = new List<User>();
            listUsers.ForEach(
                user =>
                {
                    if (user.FaceId!=null)
                    {
                        listFaceIds.Add(user);
                    }
                });

            vce.Stop();
            RenderTargetBitmap bmp = new RenderTargetBitmap(
            (int)vce.ActualWidth,
            (int)vce.ActualHeight,
            96, 96, PixelFormats.Default);
            bmp.Render(vce);
            BitmapEncoder encoder = new JpegBitmapEncoder();//默认使用JPG格式保存，可以切换成其他格式，因为JPG格式的文件更小，所以这里推荐使用
            encoder.Frames.Add(BitmapFrame.Create(bmp));
            bool compareResult = false;
            User tempUser = new User();
            using (MemoryStream ms = new MemoryStream())
            {
                encoder.Save(ms);
                byte[] data = ms.ToArray();//此处不必保存,因为之后将直接用到byte[]
                foreach (var item in listFaceIds)
                {
                    var images = new byte[][] { data, item.FaceId };
                    TaskAwaiter<JObject> awaiter = TFaceCompare(images).GetAwaiter();
                    var result = awaiter.GetResult();
                    if (result["result_num"].ToString() != "0")
                    {
                        JToken Rresult = result["result"][0];
                        if (double.Parse(Rresult["score"].ToString())>=90)
                        {
                            compareResult = true;
                            tempUser = item;
                            break;
                        }
                    }
                }
                if (compareResult)
                {
                    compareResult = false;
                    if (App.user==null)
                    {
                        App.user = tempUser;
                    }
                    opInterface.AddLog(new OperationLog() { UserName = tempUser.UserName, OperatTime = DateTime.Now, Actions = "登录成功" });
                    DefaultWindow defaultWin = new DefaultWindow();
                    this.Close();
                    defaultWin.Show();
                    defaultWin.btnCurrentUser.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                }
                else
                {
                    MessageBox.Show("请确认是已否录入您的信息!","Error",MessageBoxButton.OK,MessageBoxImage.Error);
                    vce.Pause();
                    Thread.Sleep(1000);
                    vce.Play();
                }

            }
        }
        private void FaceIdentify_Closed(object sender, System.EventArgs e)
        {
            vce.Stop();
            if(App.user==null)
            {
                Login winLogin = new Login();
                winLogin.Show();
            }
        }

        private void deleteFile(string filePath)
        {
            if(File.Exists(filePath))
            {
                File.Delete(filePath);
            }
        }
    }
}
